﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Xml;
using System.Diagnostics;
using System.Threading;
using System.Configuration;
using System.IO;
using SMSPanasonic.Business;
namespace SMSPanasonic
{
    class SMSMTSend:SMSPanasonicMTRouterSending
    {
        public SMSMTSend(SmsRouter sms_router, int thread_id, long retry_on_fail_req_duration, long retry_on_time_out_req_duration, int retry_on_fail_req_times, int retry_on_time_out_req_times)
        {
            //Id cua Router
            this.SmsRouter = sms_router;
            //Router dang phuc vu cho Thread nao
            this.ThreadID = thread_id;
            //Object cua Router dung de gui tin nhan
            this.SmsRouterObject = new SAMI_SMSService.SMSWebService();
            this.RetryOnFailReqDuration = retry_on_fail_req_duration;
            this.RetryOnTimeOutReqDuration = retry_on_time_out_req_duration;
            this.RetryOnFailReqTimes = retry_on_fail_req_times;
            this.RetryOnTimeOutReqTimes = retry_on_time_out_req_times;
            //this.SmsRouter = new SmsRouter(this.RouterID);
            ((SAMI_SMSService.SMSWebService)this.SmsRouterObject).Url = SmsRouter.RouterURL.IsNull ? "" : SmsRouter.RouterURL.Value;
            ((SAMI_SMSService.SMSWebService)this.SmsRouterObject).Timeout = Properties.Settings.Default.ServiceTimeOut;
        }

        public string RouterURL
        {
            get
            {
                return (SmsRouter.RouterURL.IsNull ? "" : SmsRouter.RouterURL.Value + ";") + (SmsRouter.RouterURL2.IsNull ? "" : SmsRouter.RouterURL2.Value);
            }
            set
            {
                ((SAMI_SMSService.SMSWebService)SmsRouterObject).Url = value;
            }
        }

        public override void SendSms(List<SmsMtWaiting> smsMtWatingList)
        {
            try
            {
                string[][] arrayGuidReturn = new string[][] { };
                string message_return = "";

                //PublicKey này cấp cho HSG
                SAMI_SMSService.SMSWebService service = new SMSPanasonic.SAMI_SMSService.SMSWebService();
                string strPublicKey = this.SmsRouter.PublicKey.Value; // "<BitStrength>512</BitStrength><RSAKeyValue><Modulus>svMuSes1t1GoOuXUXcFnhB/KF/Z2401n/VxMlF2jZaRYHmXayuAofWjJCV2WvPS3wu29R5FHZk192vP7khGUXQ==</Modulus><Exponent>AQAB</Exponent></RSAKeyValue> ";
                int CooperateID = Properties.Settings.Default.CooperateID;// 46011; //Mã đang cấp cho PepsiCo là 46011

                int iResult = 0;

                //Tạo dữ cấu trúc dữ liệu cho DataSet
                DataSet ds = new DataSet();
                DataTable dt = new DataTable();
                dt.TableName = "SMSOut";

                DataColumn myDataColumn;

                myDataColumn = new DataColumn();
                myDataColumn.DataType = Type.GetType("System.String");
                myDataColumn.ColumnName = "DestAddr";
                dt.Columns.Add(myDataColumn);

                myDataColumn = new DataColumn();
                myDataColumn.DataType = Type.GetType("System.String");
                myDataColumn.ColumnName = "ShortCode";
                dt.Columns.Add(myDataColumn);

                myDataColumn = new DataColumn();
                myDataColumn.DataType = Type.GetType("System.String");
                myDataColumn.ColumnName = "Message";
                dt.Columns.Add(myDataColumn);

                myDataColumn = new DataColumn();
                myDataColumn.DataType = Type.GetType("System.String");
                myDataColumn.ColumnName = "CooperateGUID";
                dt.Columns.Add(myDataColumn);

                myDataColumn = new DataColumn();
                myDataColumn.DataType = Type.GetType("System.String");
                myDataColumn.ColumnName = "SmsInGUID";
                dt.Columns.Add(myDataColumn);

                myDataColumn = new DataColumn();
                myDataColumn.DataType = Type.GetType("System.String");
                myDataColumn.ColumnName = "CDRIndicator";
                dt.Columns.Add(myDataColumn);

                myDataColumn = new DataColumn();
                myDataColumn.DataType = Type.GetType("System.String");
                myDataColumn.ColumnName = "MTType";
                dt.Columns.Add(myDataColumn);

                dt.Rows.Clear();
                //Sinh dữ liệu cho DataSet
                foreach (SmsMtWaiting mt_item in smsMtWatingList)
                {
                    DataRow dr;
                    dr = dt.NewRow();
                    dr["DestAddr"] = mt_item.DestAddr.Value; //Số khách hàng cần gửi tin nhắn
                    dr["ShortCode"] = mt_item.ShortCode.Value; //comboBoxServiceNumber.SelectedItem.ToString(); //Số dịch vụ dùng để gửi tin
                    dr["Message"] = mt_item.Message.Value; //Nội dung cần gửi
                    dr["CooperateGUID"] = mt_item.MtGuid.Value.ToString();
                    dr["SmsInGUID"] = mt_item.MoGuid.IsNull ? "" : mt_item.MoGuid.Value.ToString();
                    dr["CDRIndicator"] = mt_item.CDRIndicator.Value; // "FREE"
                    dr["MTType"] = mt_item.MTType.Value; // "AN"; //Annoucement

                    dt.Rows.Add(dr);
                }

                ds.Tables.Add(dt);
                string sTrans = Guid.NewGuid().ToString("N");
                //Chuyển DataSet thành XML
                XmlElement xml = Xml.Serialize(ds);

                string inputString;
                string bitStrengthString = strPublicKey.Substring(0, strPublicKey.IndexOf("</BitStrength>") + 14);
                strPublicKey = strPublicKey.Replace(bitStrengthString, "");
                int bitStrength = Convert.ToInt32(bitStrengthString.Replace("<BitStrength>", "").Replace("</BitStrength>", ""));
                inputString = xml.OuterXml;

                //Sinh MD5 cho chuỗi xml - Hàm SendEncryptSMSMessage sẽ giải mã chuỗi XML sau đó kiểm tra CheckSum xem nội dung có bị thay đổi không
                string checksum = Cryptography.getMd5Hash(inputString);
                //Mã hóa XML bằng PublicKey
                inputString = Cryptography.EncryptString(inputString, bitStrength, strPublicKey);

                //Gọi webservice gửi tin, tham số (true) cho phép tự động tách tin khi nội dung gửi quá 160 ký tự. Nếu đặt là (false) phần quá sẽ bị cắt

                //inputString = XMLCompression.Compress(inputString);
                //service.Url = @"http://118.70.180.183:8888/SMSMTService/SMSWebService.asmx";
                try
                {
                    iResult = service.SendEncryptMT(sTrans, CooperateID, inputString, checksum , ref arrayGuidReturn, ref message_return);
                }
                catch (Exception ex)
                {
                    Common.WriteLog(ex, "Call SentEncryptMT");
                    //Neu loi xay ra thi dua lai vao MtWaiting
                    DataTable mtWaitingTable = MakeBulkTable.MakeSmsMtWaitingTable();
                    foreach (SmsMtWaiting mt_item in smsMtWatingList)
                    {
                        DataRow row = mtWaitingTable.NewRow();

                        row["MtGuid"] = mt_item.MtGuid.Value;
                        row["MoGuid"] = mt_item.MoGuid.IsNull ? Guid.Empty : mt_item.MoGuid.Value;
                        row["ShortCode"] = mt_item.ShortCode.IsNull ? string.Empty : mt_item.ShortCode.Value;
                        row["DestAddr"] = mt_item.DestAddr.IsNull ? string.Empty : mt_item.DestAddr.Value;
                        row["OperatorID"] = mt_item.OperatorID.IsNull ? -1 : mt_item.OperatorID.Value;
                        row["Message"] = mt_item.Message.IsNull ? string.Empty : mt_item.Message.Value;
                        row["CooperateID"] = mt_item.CooperateID.IsNull ? -1 : mt_item.CooperateID.Value;
                        row["Status"] = mt_item.Status.IsNull ? string.Empty : mt_item.Status.Value;
                        row["SentTime"] = DateTime.Now;
                        row["CDRIndicator"] = mt_item.CDRIndicator.IsNull ? "FREE" : mt_item.CDRIndicator.Value;
                        row["MTType"] = mt_item.MTType.IsNull ? "AN" : mt_item.MTType.Value;
                        row["RetryOnFailReqTimes"] = Properties.Settings.Default.RetryOnFailReqTimes;
                        row["RetryOnTimeOutReqTimes"] = Properties.Settings.Default.RetryOnTimeOutReqTimes;
                        row["RetryOnFailReqDuration"] = Properties.Settings.Default.RetryOnFailReqDuration;
                        row["RetryOnTimeOutReqDuration"] = Properties.Settings.Default.RetryOnTimeOutReqDuration;

                        mtWaitingTable.Rows.Add(row);
                    }

                    mtWaitingTable.AcceptChanges();
                    try
                    {
                        SQLCommand.BulkCopy("SmsMtWaiting", mtWaitingTable);
                    }
                    catch (Exception ex_bulk_copy)
                    {
                        Common.WriteLog(ex_bulk_copy, "SQLCommand.BulkCopy");
                    }

                    
                }

                // Mang arrayGuidReturn[][] bao gom CooperateGUID cua doi tac gui, duyet tuan tu tu tren xuong duoi
                // neu thanh cong gia tri tra ve la "true", neu khac la ma loi

                // Neu iResult = 1 => tat ca cac ban ghi duoc gui thanh cong
                // Neu iResult = -1, co loi xay ra, duyet tung phan tu trong arrayGuidReturn de xac dinh ban ghi thanh cong va khong thanh cong
                if (iResult == 1)
                {
                    foreach (SmsMtWaiting mt_item in smsMtWatingList)
                    {
                        SmsMtStatistic mt_statistic = new SmsMtStatistic(mt_item.MtGuid);
                        mt_statistic.Status = "SENT-SAMI";
                        mt_statistic.Save();

                        SmsMtReport sms_mt_report = new SmsMtReport(mt_item.MtGuid);
                        sms_mt_report.Status = "SENT-SAMI";
                        sms_mt_report.SentTime = DateTime.Now;
                        sms_mt_report.Save();
                    }
                } 
                else
                if (arrayGuidReturn.Length > 0 && arrayGuidReturn[0].GetUpperBound(0) >= 0)
                {
                    for (int j = 0; j < arrayGuidReturn[0].Length; j++)
                    {
                        //sResult += "CooperateGuid:" + arrayGuidReturn[0][j] + "=" + arrayGuidReturn[1][j] + "\r\n";
                        //Neu arrayGuidReturn tra ve TRUE la gui thanh cong, khac TRUE la khong thanh cong dong thoi chinh la thong bao loi.
                        if (arrayGuidReturn[1][j].ToUpper() == "TRUE")
                        {
                            SmsMtStatistic mt_statistic = new SmsMtStatistic(new System.Data.SqlTypes.SqlGuid(arrayGuidReturn[0][j]));
                            mt_statistic.Status = "SENT-SAMI";
                            mt_statistic.SentTime = DateTime.Now;
                            mt_statistic.Save();

                            SmsMtReport sms_mt_report = new SmsMtReport(new System.Data.SqlTypes.SqlGuid(arrayGuidReturn[0][j]));
                            sms_mt_report.Status = "SENT-SAMI";
                            sms_mt_report.SentTime = DateTime.Now;
                            sms_mt_report.Save();

                        }
                        else
                        {
                            SmsMtStatistic mt_statistic = new SmsMtStatistic(new System.Data.SqlTypes.SqlGuid(arrayGuidReturn[0][j]));
                            mt_statistic.Status = "ERROR";// arrayGuidReturn[1][j].ToUpper();
                            mt_statistic.Save();

                            Logs logs = new Logs();
                            logs.LogSource = "Trong luc gui thi nhan duoc loi tra ve tu SAMI";
                            logs.LogMessage = arrayGuidReturn[1][j].ToUpper();
                            logs.LogTime = DateTime.Now;
                            logs.LogTrace = "SendSms Item";
                            logs.LogType = "SendSms";
                            logs.Status = new System.Data.SqlTypes.SqlBoolean(true);
                            logs.Save();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Common.WriteLog(ex, "SendSms");
            }


        }
    }
}
